from typing import List, Optional
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, and_, delete
from sqlalchemy_crud_plus import CRUDPlus

from modules.system.models.data_permission import SysRoleDataPermission, SysDataPermissionRule
from modules.system.schemas.data_permission_schemas import (
    RoleDataPermissionCreate,
)


class RoleDataPermissionRepository(CRUDPlus[SysRoleDataPermission]):
    """角色数据权限关联仓储类"""

    async def get_by_role_id(self, db: AsyncSession, role_id: int) -> List[SysRoleDataPermission]:
        stmt = select(SysRoleDataPermission).where(
            and_(SysRoleDataPermission.role_id == role_id, SysRoleDataPermission.status == True)
        )
        res = await db.execute(stmt)
        return list(res.scalars().all())

    async def get_by_rule_id(self, db: AsyncSession, rule_id: int) -> List[SysRoleDataPermission]:
        stmt = select(SysRoleDataPermission).where(
            and_(SysRoleDataPermission.rule_id == rule_id, SysRoleDataPermission.status == True)
        )
        res = await db.execute(stmt)
        return list(res.scalars().all())

    async def get_role_rules(self, db: AsyncSession, role_ids: List[int]) -> List[SysDataPermissionRule]:
        if not role_ids:
            return []
        stmt = (
            select(SysDataPermissionRule)
            .join(
                SysRoleDataPermission,
                and_(
                    SysDataPermissionRule.id == SysRoleDataPermission.rule_id,
                    SysRoleDataPermission.role_id.in_(role_ids),
                    SysRoleDataPermission.status == True,
                ),
            )
            .where(SysDataPermissionRule.status == True)
            .distinct()
        )
        res = await db.execute(stmt)
        return list(res.scalars().all())

    async def create(self, db: AsyncSession, data: RoleDataPermissionCreate) -> SysRoleDataPermission:
        return await self.create_model(db, data)

    async def delete_by_role_id(self, db: AsyncSession, role_id: int) -> bool:
        await db.execute(delete(SysRoleDataPermission).where(SysRoleDataPermission.role_id == role_id))
        return True

    async def delete_by_rule_id(self, db: AsyncSession, rule_id: int) -> bool:
        await db.execute(delete(SysRoleDataPermission).where(SysRoleDataPermission.rule_id == rule_id))
        return True

    async def delete_by_id(self, db: AsyncSession, pk: int) -> bool:
        return await self.delete_model(db, pk)


role_data_permission_dao = RoleDataPermissionRepository(SysRoleDataPermission)